home *** CD-ROM | disk | FTP | other *** search
- ;«RM92»«TS8,16,24,32,40,48»
- ; updated 5/21/91
-
- DOSSEG
- .MODEL MEDIUM, BASIC
-
- .DATA
- EXTRN B$TEMPDATA:WORD ;inside FDATA, 128 byte buffer
- EXTRN B$STRINGLEN:WORD ;inside FDATA, empty string descriptor
- EXTRN B$STRINGOFF:WORD ;inside FDATA
-
- .CODE
- EXTRN B$ASSN:FAR ;This allows QBASIC to manipulate fixed length string
- EXTRN B$STDL:FAR ;This creates null strings
-
- ; Please do not remove
- Copyright DB 13,10,'Copyright Copr. (C) 1991 Sidney J. Kelly',13,10
- Copyright1 DB 'All Rights Reserved',13,10,26
-
- COPY_STRING_BUFFER macro
- ;;Copies user input string to a buffer (FDATA.ASM)
- ;;Does not test length of string!
- ;;Uses SI,DI,ES,AX,CX,BX
- ;;Assumes BX = address of string descriptor
- ;; CX = length of string
- ;; DS = segment of string
- ;; ES = DGROUP
- ;; Direction Flag clear, CLD
- ;;Trashes AX, SI, DI and CX
- Mov SI,[BX+2] ;; put offset of string in SI
- Mov DI,OFFSET B$TEMPDATA ;; put address of buffer in DI
- ;;Rep MOVSB ;; copy the string to buffer
- ;;The following is faster than a MOVSB routine
- Shr CX,1 ;; convert bytes to word
- Rep MOVSW ;; move DS:SI to ES:DI
- ADC CX,CX ;; CX=1 if bytes were odd, 0 if even
- Rep MOVSB ;; copy the odd byte if there was one
- endm
-
- ASCII_Space EQU 32
-
- EVEN
- ;memory rather than stack used allow deep nesting of routine
- ;prevents use under OS/2 or protected mode
- Right_Edge dw 0 ; right edge of Buffer
- Max_Cursor dw 0 ; dimension of max cursor
- Min_Cursor dw 0 ; dimension of min cursor
- Orig_Cursor dw 0 ; original cursor shape
- Exit_Key dw 0 ; key hit to exit routine
- Old_BP dw 0 ; temp storage for BP, to correct
- ; for bug in early PC video bios
- ; that changes BP
-
- Max_Len db 0 ; max length of Result$
- Curr_Page db 0 ; current video page
- Insert_State db 0 ; -1 = insert on, 0 = insert off
- Start_Row db 0 ; Starting Row
- Start_Col db 0 ; Starting Column
- Curr_Row db 0 ; (never really used)
- Curr_Col db 0 ; Current column location
- Max_Right db 0 ; rightmost column
- Curr_V_Mode db 0 ; fix for rom BIOS error
- ; in AST 386/AMI 386 BIOS
-
- ;=======================================================================
- ; DECLARE FUNCTION EDITOR$ (BYVAL ROW%, BYVAL COL%, BYVAL LENGTH%, _
- ; BYVAL ATTR%, INPUT$, FILTER$, EXITKEY%)
- ; Result$ = EDITOR$ (ROW%, COL%, LENGTH%, ATTR%, FILTER$, EXITKEY%)
- ; Compatible input editor, allowed keystrokes limited by Filter$.
- ; Extended keys not recognized, primarily for alpha-numeric input only
- ; Allows editing using any video page supported by the video system
- ;
- ; Editing keys recognized;
- ; Home: move cursor to beginning of window
- ; Insert; toggle insert mode, default mode is insert on
- ; End; move cursor to end of window
- ; Del: moves string left, deletes character under cursor
- ; Backspace: moves string left, deletes character to left of cursor
- ; Currently ESC, ENTER, TAB, and SHIFT-TAB will end the routine
- ;
- ; Input:
- ; Row: Row on screen 1 to 50, no range check is performed
- ; Col: Starting Column 1 to 80, no range check is performed
- ; Length: Length of editing window, no range check performed
- ; If extends past right border, then wraps to lower line.
- ; Attr: Color attribute for window (back * 16 + foreground color)
- ; Input$: allows programmer to feed routine an existing string
- ; for editing. The Input$ is not changed, only Result$ is.
- ; Filter$: the input filter string, if LEN(Filter$) = 0 then
- ; every key is o.k.
- ; Exitkey%: the scan code of the key used to exit the routine
- ; currently ESC, ENTER, TAB, and SHIFT-TAB recognized
- ;=======================================================================
-
- EVEN
- EDITOR PROC FAR BASIC USES SI DI, ROW:WORD, COL:WORD, \
- LENGTHH:WORD, ATTR:WORD, INPUT:WORD, FILTER:WORD, EXITKEY:WORD
-
- Assume DS:@data
- Setup:
- Mov Old_BP,BP ; store it because bios may change BP
- ; and we need it to access stack correctly
- Mov AX,@data ; this is a pointer to DGROUP
- Mov ES,AX ; move near data seg to ES
- Assume ES:@data ; tell assembler
- CLD ; clear direction flag for safety
- Mov AX,2020h ; load spaces in AX
- Mov CX,44 ; count 44 words, 88 bytes to be safe
- Mov DI,OFFSET B$TEMPDATA ; load offset of buffer in DI
- Rep STOSW ; fill buffer (ES:DI) with spaces
- Mov AL,0FFh ; make AL = -1 to record using insert mode
- Mov Insert_State,AL
- Mov AX,LENGTHH ; get length of output string into AX (BYVAL)
- Or AX,AX ; make sure not 0
- JNZ Setup1 ; not 0, so jump ahead
- Mov AX,1 ; make AX = 1, so can read one character
- Jmp Short Setup2 ; jump ahead
-
- Setup1:
- Cmp AL,80 ; make sure LENGTHH < than size of buffer
- JBE Setup2 ; range o.k. so continue
- Mov AL,80 ; else make it 80 character max
-
- Setup2:
- Mov Max_Len,AL ; store in CSEG
- Mov BL,AL ; store temporarily in BL
- Dec BL ; make length 0 biased
- Mov AX,ROW ; get starting row into AX (BYVAL)
- Dec AL ; make 0 bias
- Mov Start_Row,AL ; store value
- Mov Curr_Row,AL ; put cursor at beginning
- Mov AX,COL ; get starting column into AX (BYVAL)
- Dec AL ; make 0 bias
- Mov Start_Col,AL ; store value
- Mov Curr_Col,AL ; put cursor at beginning
- Add AL,BL ; add Curr_Col+(Max_Len-1)
- Mov Max_Right,AL ; store in Max_Right
- Mov AX,OFFSET B$TEMPDATA ; load offset of buffer in AX
- Add AL,BL ; add 0 biased length to buffer offset
- Mov Right_Edge,AX ; store in memory for fast access
-
- Get_Video_Info:
-
- Mov AH,0Fh ; get current page number in BH
- Int 10h
- Mov Curr_Page,BH ; save current page number
- Mov Curr_V_Mode,AL ; save current video mode
- Cmp AL,7 ; mono mode?
- JNE Try_Color ; nope, try color
- Mov AH,3 ; get current default size
- Int 10h
- Mov Orig_Cursor,CX ; save current cursor shape
- Mov CX,000Ch ; use mono sizing
- Mov Max_Cursor,CX ; set max cursor size
- Mov AH,1 ; to model insert mode
- Int 10h
- Mov CH,0Bh ; set min cursor size for mono
- Mov Min_Cursor,CX ; save it
- Jmp Short Other_Info ; skip over color sections
-
- Try_Color:
- Mov AH,3 ; BH must contain current page number
- Int 10h ; returns current cursor in CX
- Mov Orig_Cursor,CX ; save current cursor shape
- Mov DX,CX ; copy value in DX too for temporary storage
- Xor CH,CH ; clear top value so it is 0
- Mov Max_Cursor,CX ; store maximum size in CSEG
- Mov AH,1 ; AL contains current video mode
- Int 10h ; set cursor to maximum size
- Mov CL,DL ; get back temporary value from DX
- Mov CH,DL
- Dec CH ; reduce top scan value by one
- Mov Min_Cursor,CX ; store in Min value
-
- Other_Info:
- Call Near Ptr Mov_Cursor ; move cursor where desired
- Mov BP,Old_BP ; restore BP in case bios changed it
- Mov AX,ATTR ; get attribute in AX (BYVAL)
- Or AX,AX ; see if it is zero
- JNZ @f
- Mov AL,7 ; use default of White on Black
- @@:
- Mov BL,AL ; put display attribute in BL
- ; BH already contains current page
- Mov AX,0920h ; get ready to print spaces
- Mov CL,Max_Len ; write spaces on screen
- Xor CH,CH ; print spaces using function 9
- Int 10h ; as this allows us to set attributes
- ; but it does not move cursor
- ; so this is the only time we use it
- Mov DL,CL ; store Max_Len in DL
- Xor DH,DH ; clear DH
- Mov BP,Old_BP ; restore BP in case bios changed it
- Mov BX,INPUT ; get address of input string
- Mov CX,[BX] ; get length in CX
- JCXZ Clear_Keyb ; if LEN=0 then skip ahead
- Cmp CX,DX ; is LEN > Max_Len
- JBE @f ; it is less than or equal so jump ahead
- Mov CX,DX ; make LEN of Imput$ = Max_Len
- @@:
- Mov DX,CX ; store LEN in DX, because CX will be trashed
- COPY_STRING_BUFFER ; copy Input$ to buffer MACRO
- Mov AL,Curr_Col ; get starting column
- Add AL,DL ; add LEN to Start_Row
- Mov BL,Max_Right ; get address of right side
- Cmp AL,BL ; see if AL > Max_Right
- JBE @f ; if less than or equal, skip ahead
- Mov AL,BL ; limit cursor to right side of buffer
- @@:
- Mov Curr_Col,AL ; move cursor to end of string
- Call Near Ptr Show_String ; show input string
-
- EVEN
- Clear_Keyb:
- ; make sure buffer is empty when we start
- ; there are faster ways, but this is the most compatible way
- ; faster way will be incompatible with Tandy machines
-
- Mov AH,1 ; clear keyboard buffer
- Int 16h
- JZ Main ; no key waiting so quit
- Xor AH,AH ; get key into AX
- Int 16h
- Jmp Short Clear_Keyb ; loop until buffer is empty
-
- EVEN
- Main: ; this is the main loop, most everything returns here
- Xor AH,AH ; this will wait until a key is pressed
- Int 16h ; use BIOS so CTRL-C, CTRL-BREAK wont
- ; kill program
- Or AL,AL ; is it an extended key?
- JZ Parse_Extended ; yes
- Cmp AL,ASCII_Space ; below ASCII 32 (space character)
- JB Parse_Control ; yes, treat as control key
- Mov BP,Old_BP ; restore BP in case bios changed it
- Mov BX,FILTER ; check if an allowed key
- Mov CX,[BX] ; move length ito CX, if LEN(FILTER$) = 0
- Jcxz Add_String ; then, by definition, got the right key
- Mov DI,ES:[BX+2] ; move address of FILTER$ to DI
- Repne Scasb ; search for match
- JNE Err_Beep ; did we search entire string?, if yes Beep
-
- Add_String:
- Jmp Add_Char ; add AL to string buffer & display it
-
- EVEN
- Err_Beep:
- Mov AX, 0E07h ; Write ASCII 7 character
- Int 10h ; (bell) to console (BEEP)
- ; this makes the beep CPU speed independent
- Jmp Short Clear_Keyb; clear KBD buffer to prevent excess keys
-
- EVEN
- Parse_Control: ; parse control keys
- Mov Exit_Key,AX ; store exit key in CSEG buffer
- Cmp AL,9 ; Is it a tab key?
- JE Quit1 ; yes, so quit
- Cmp AL,13 ; Is it a carriage return key?
- JE Quit1 ; yes, so quit
- Cmp AL,27 ; Is it an escape key?
- JE Quit1 ; yes, so quit
- Cmp AL,8 ; Is it backspace?
- JNE Main ; not any of the above so reloop
-
- ; Send BackSpace ; else, send backspace
- Mov AL,Curr_Col ; get current column
- Cmp AL,Start_Col ; see > starting column
- JA Back_S ; it is, so o.k.
- Jmp Err_Beep ; else, at left margin can go no more
- Back_S:
- Dec AL ; reduce current column by one
- Mov Curr_Col,AL ; store result
- Call Near Ptr Mov_Buff_Left ; move buffer left
- Call Near Ptr Show_String ; display changes
- Jmp Main
-
- EVEN
- Quit1: ; lilly pad
- Jmp Quit
-
- EVEN
- Parse_Extended: ; parse extended keys
- Mov Exit_Key,AX ; store exit key in CSEG buffer
- Cmp AH,15 ; is it shift-tab
- JE Quit1 ; yes, so quit
- Cmp AH,52h ; is it Insert
- JNE @f ; nope, so jump ahead
-
- Toggle_Insert: ; Toggle Insert mode
- Mov AL,Insert_State ; get current state
- Not AL ; flip all bits 0 to FFh, or FFh to 0
- Mov Insert_State,AL ; store current result
- Mov CX,Max_Cursor ; assume max cursor size
- Or AL,AL ; is AL = 0, want min size?
- JNZ Tog_1 ; nope, wanted max size
- Mov CX,Min_Cursor ; else get min cursor
- Tog_1:
- Mov AH,1 ; set current scan lines
- Mov AL,Curr_V_Mode ; fix AST/AMI 386 Rom BIOS error
- Int 10h
- Jmp Main ; hop back to main loop
-
- @@:
- Cmp AH,4Dh ; is it right arrow
- JNE @f ; not a special key so continue
-
- Mov_Right: ; Move cursor right
- Mov AL,Curr_Col ; get current column
- Cmp AL,Max_Right ; get right border
- JB Mov_R ; are we left of right border
- Jmp Err_Beep ; nope, so beep
- Mov_R:
- Inc AL ; move current column right
- Mov Curr_Col,AL ; update memory variable
- Call Near Ptr Mov_Cursor ; move cursor where desired
- Jmp Main
-
- @@:
- Cmp AH,4Bh ; is it a left arrow
- JNE @f ; not that key so continue
-
- Mov_Left: ; Move cursor left
- Mov AL,Curr_Col
- Cmp AL,Start_Col ; are we right of left border
- JA Mov_L
- Jmp Err_Beep ; nope, so beep
- Mov_L:
- Dec AL
- Mov Curr_Col,AL
- Call Near Ptr Mov_Cursor ; move cursor where desired
- Jmp Main
-
- @@:
- Cmp AH,47h ; is it the home key
- JNE @f ; not that key so continue
-
- Mov_Home: ; Cursor Home, to start of string
- Mov AL,Start_Col ; get starting column
- Mov Curr_Col,AL ; make current column = starting
- Call Near Ptr Mov_Cursor ; move cursor where desired
- Jmp Main ; hop back into main loop
-
- @@:
- Cmp AH,53h ; is it Del key
- JNE @f ; not that key so continue
-
- Del_Char: ; else, delete current character
- Call Near Ptr Mov_Buff_Left ; move string at right of cursor, left
- Call Near Ptr Show_String ; but don't move cursor
- Jmp Main
-
- @@:
- Cmp AH,4Fh ; is it the end key?
- JE Mov_End ; yes
- Jmp Main ; nope so start again
-
- Mov_End: ; Move to End of buffer
- Mov AL,Max_Right
- Mov Curr_Col,AL
- Call Near Ptr Mov_Cursor ; move cursor where desired
- Jmp Main
-
- EVEN
- Quit:
- Mov AH,1 ; reset cursor to original size
- Mov AL,Curr_V_Mode ; fix AST/AMI 386 Rom BIOS error
- Mov CX,Orig_Cursor
- Int 10h
- Mov BP,Old_BP ; restore BP in case bios changed it
- Mov BX,EXITKEY ; get address of EXITKEY
- Mov AX,Exit_Key ; save ExitKey
- Or AL,AL ; make sure return value in AL
- JNZ @f
- Mov AL,AH ; if not then move to AL
- @@:
- Xor AH,AH ; and make sure that AH = 0
- Mov [BX],AX ; store in EXITKEY
-
- CopyString:
- Mov AL,Max_Len ; get length of string in AX
- Xor AH,AH ; clear high byte
- Mov CX,AX ; put length in CX
- Mov DI,OFFSET B$TEMPDATA ; move address of string to DI
- Dec AX ; make Max_Len zero biased
- Add DI,AX ; get last byte (beginning + length)
- Mov AL,20h ; look for trailing spaces
- STD ; set direction down, scan backwards
- Repz Scasb ; search for non match (ES:DI w/ AL)
- CLD ; clear direction flag
- JZ Err_Quit ; all spaces so quit
- Inc CX ; remove 1 byte overrun of SCASB
-
- ; standard way to return a string to QBASIC
- Push DS ; Store the Data Segment
- Mov AX, OFFSET B$TEMPDATA
- Push AX ; Store offset of string
- Push CX ; Store LENGTH of string
- Push DS ; Store the Data Segment
- Mov AX, OFFSET B$STRINGLEN
- Push AX ; Store Descriptor of string
- Xor AX,AX ; tell Basic it is a variable string
- Push AX ; Store a 0
- Call B$ASSN ; copy string into BASIC space
- Mov AX, OFFSET B$STRINGLEN ; address of descriptor
- Ret
-
- EVEN
- Err_Quit:
- ; this returns a null string if have an error
- Mov AH,1 ; reset cursor to original size
- Mov CX,Orig_Cursor
- Mov AL,Curr_V_Mode ; fix AST/AMI 386 Rom BIOS error
- Int 10h
-
- Err_Quit1:
- Mov BP,Old_BP ; restore BP in case bios changed it
- Mov BX,EXITKEY
- Xor AX,AX ; return no exit key
- Mov [BX],AX
- Mov AX, OFFSET B$STRINGLEN ; put address of
- Push AX ; descriptor in AX
- Call B$STDL ; make it a null string
- Mov AX, OFFSET B$STRINGLEN ; put address of descriptor in AX
- Ret
- EDITOR ENDP
-
- ;--------------------------- Jump Section-------------------------
- ;simple procedures with local labels so that they will not have public names
- ;and take up space in the .OBJ file with use full PROC directives
-
- EVEN
- Mov_Cursor Label Near ; this is a common routine
- Mov DH,Curr_Row ; move cursor to that location
- Mov DL,Curr_Col ; Row at Curr_Row, Col at Curr_Col
- Mov BH,Curr_Page ; this allows use of any video page
- Mov AH,2
- Int 10h
- Retn
-
-
- EVEN
- Show_String Label Near
- ; turn off cursor until printing is complete
- Mov BH,Curr_Page ; get current page in BH
- Mov AH,3 ; read cursro info
- Int 10h ; Clear cursor by
- Or CH,20h ; by turning on bit 5 of CH
- Mov AH,1 ; set Cursor size function
- Mov AL,Curr_V_Mode ; fix AST/AMI 386 Rom BIOS error
- Int 10h ; do it
-
- Mov AH,2 ; move cursor to beginning of string
- Mov DH,Start_Row ; note BH contains Curr_Page
- Mov DL,Start_Col ; load starting Row & Column
- Int 10h
-
- Mov CL,Max_Len ; determine how many bytes to show
- Xor CH,CH ; clear CH
- Mov SI,OFFSET B$TEMPDATA ; get the offset of buffer into SI
- EVEN
- Looper1:
- Lodsb ; load DS:SI into AL
- Mov AH,0Eh ; display AL & move cursor
- Int 10h ; (now hidden)
- Loop Looper1
-
- Mov AH,3 ; make cursor visable again
- Int 10h ; get current cursor
- And CH,11011111b ; clear bit 5
- Mov AH,1 ; reset cursor so it is now displays
- Mov AL,Curr_V_Mode ; fix AST/AMI 386 Rom BIOS error
- Int 10h
- Jmp Mov_Cursor ; move cursor to desired location
- ; & return from whence we came
-
- EVEN
- Add_Char Label Near
- Mov CX,AX ; temporarily store AX in CX
- Mov AL,Insert_State ; see if Insert Mode is on
- Cmp AL,0 ; i.e. is AL <> 0?
- JE Add_Char1 ; nope, AL = 0 insert off, skip ahead
- Mov AL,Curr_Col ; get current location
- Cmp Max_Right,AL ; are we at right column edge?
- JE Add_Char1 ; yes so add to buffer, & ignore Insert mode
-
- Mov_Buff_Right:
- ; must preserve CX
- Mov DX,CX ; store CX in DX to preserve CX
- Mov BX,Right_Edge ; load BX w/ right side of buffer
- Mov DI,BX ; set destination in ES:DI
- Dec BX ; reduce right side by one
- Mov SI,BX ; set source in DS:SI
- Mov AL,Curr_Col ; find how many words to
- Mov CL,Max_Right ; right of cursor
- Sub CL,AL
- Inc CL ; remove 0 bias
- Xor CH,CH ; number of bytes in CX
- Std ; use STD to count down
- Rep MovSB
- Cld ; reset flag
- Mov CX,DX ; restore CX to original value
-
- Add_Char1:
- Mov SI, OFFSET B$TEMPDATA ; get address of buffer in SI
- Mov AL,Start_Col
- Mov BL,Curr_Col
- Sub BL,AL
- Xor BH,BH
- Mov DS:[SI+BX],CL
- Call Near Ptr Show_String
- Mov AL,Curr_Col
- Cmp AL,Max_Right
- JB Add_Char2
- Jmp Main
- Add_Char2:
- Inc AL ; increment the cursor location
- Mov Curr_Col,AL
- Call Near Ptr Mov_Cursor ; move cursor where desired
- Jmp Main ; start loop again
-
- EVEN
- Mov_Buff_Left Label Near
- ; moves the buffer left to erase a character or characters
- Mov BX,OFFSET B$TEMPDATA
- Mov AL,Start_Col
- Mov CL,Curr_Col
- Sub CL,AL
- Xor CH,CH
- Add BX,CX
- Mov DI,BX ; put destination in ES:DI
- Inc BX
- Mov SI,BX ; put source in DS:SI
- Mov CL,Max_Right
- Mov AL,Curr_Col
- Sub CL,AL
- Inc CL ; find how many words to move
- Rep MovSB
- Mov BX,Right_Edge ; get right side of buffer
- Mov AL,ASCII_Space ; put ASCII space in AL
- Mov DS:[BX],AL ; add ASCII space to end of string
- Retn
- END
-
-